package mongo

import (
	"context"
	"errors"
	"fmt"
	"go.uber.org/zap"
	"lht-go-plugins/LhtLog"
	"lht-go-plugins/LhtSettings"
	"lht-go-plugins/internal/core"
	"time"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type MongoPlugin struct {
	*core.BasePlugin
	conf   LhtSettings.MongoConfig
	client *mongo.Client
}

func NewMongoPlugin() *MongoPlugin {
	return &MongoPlugin{
		BasePlugin: core.NewBasePlugin("mongo", 2003),
	}
}

func (m *MongoPlugin) Init(cfg any) error {
	conf, ok := cfg.(*LhtSettings.MongoConfig)
	if !ok {
		return errors.New("invalid config type: expected *MongoConfig")
	}
	m.conf = *conf
	return nil
}

func (m *MongoPlugin) Start() error {
	conf := m.conf
	uri := fmt.Sprintf("mongodb://%s:%d", conf.Host, conf.Port)
	client, err := mongo.NewClient(options.Client().ApplyURI(uri))
	if err != nil {
		LhtLog.Error("MongoDB 创建客户端失败", zap.Error(err))
		return err
	}

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if err := client.Connect(ctx); err != nil {
		LhtLog.Error("MongoDB 连接失败", zap.Error(err))
		return err
	}
	if err := client.Ping(ctx, nil); err != nil {
		LhtLog.Error("MongoDB Ping 失败", zap.Error(err))
		return err
	}

	m.client = client
	LhtLog.Info("MongoDB 连接成功", zap.String("addr", conf.Host))
	return m.BasePlugin.Start(m.handleData)
}

func (m *MongoPlugin) handleData(data []byte) {
	fmt.Printf("[mongo] recv data: %s\n", string(data))
}

func (m *MongoPlugin) Stop() error {
	if m.client != nil {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		return m.client.Disconnect(ctx)
	}
	return nil
}
